Adam ================= 使用 Adam 算法更新参数权重。支持 Nesterov 动量。 算法逻辑如下: .. math:: m_t = m_{t-1} + (g_t - m_{t-1}) \cdot (1 - \beta_1) \\ v_t = v_{t-1} + (g_t^2 - v_{t-1}) \cdot (1 - \beta_2) \\ \hat{lr} = lr \cdot \frac{\sqrt{1 - \beta_2^t}}{1 - \beta_1^t} 如果不启用 Nesterov: .. math:: w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t}{\sqrt{v_t} + \epsilon} 如果启用 Nesterov: .. math:: w_t = w_{t-1} - \hat{lr} \cdot \frac{m_t \cdot \beta_1 + (1 - \beta_1) \cdot g_t}{\sqrt{v_t} + \epsilon} 输入: - **m** - 一阶矩向量地址(输入/输出)。 - **v** - 二阶矩向量地址(输入/输出)。 - **gradient** - 梯度向量地址。 - **weight** - 权重向量地址(输入/输出)。 - **beta1** - 一阶矩估计的指数衰减率。 - **beta2** - 二阶矩估计的指数衰减率。 - **beta1_power** - :math:`\beta_1^t` 的值(指针形式传入)。 - **beta2_power** - :math:`\beta_2^t` 的值(指针形式传入)。 - **eps** - 数值稳定性项 epsilon。 - **learning_rate** - 学习率。 - **nesterov** - 是否启用 Nesterov 动量(0: 不启用, 1: 启用)。 - **start** - 计算的起始索引(包含)。 - **end** - 计算的结束索引(不包含)。 - **core_mask** - 核掩码(仅适用于共享存储版本)。 输出: - **m** - 更新后的一阶矩。 - **v** - 更新后的二阶矩。 - **weight** - 更新后的权重。 支持平台: ``FT78NE`` ``MT7004`` .. note:: - 仅支持 fp32 数据类型。 **共享存储版本:** .. c:function:: void fp_adam_s(float* m, float* v, const float* gradient, float* weight, float beta1, float beta2, float* beta1_power, float* beta2_power, float eps, float learning_rate, int nesterov, int start, int end, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 25-26 #include int main(int argc, char* argv[]) { // 假设所有数据均位于DDR空间 float* m = (float*)0xC0000000; float* v = (float*)0xC1000000; float* gradient = (float*)0xC2000000; float* weight = (float*)0xC3000000; // 标量参数 float beta1 = 0.9f; float beta2 = 0.999f; float beta1_power_val = 0.9f; // beta1^1 float beta2_power_val = 0.999f; // beta2^1 float* beta1_power = &beta1_power_val; float* beta2_power = &beta2_power_val; float eps = 1e-8f; float learning_rate = 0.001f; int nesterov = 1; int start = 0; int end = 800000; // 元素总数 int core_mask = 0xff; // 使用所有核心 fp_adam_s(m, v, gradient, weight, beta1, beta2, beta1_power, beta2_power, eps, learning_rate, nesterov, start, end, core_mask); return 0; } **私有存储版本:** .. c:function:: void fp_adam_p(float* m, float* v, const float* gradient, float* weight, float beta1, float beta2, float* beta1_power, float* beta2_power, float eps, float learning_rate, int nesterov, int start, int end) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 20-21 #include int main(int argc, char* argv[]) { // 假设所有数据均位于L2/AM空间 float* m = (float*)0x10820000; float* v = (float*)0x10830000; float* gradient = (float*)0x10840000; float* weight = (float*)0x10850000; float beta1 = 0.9f; float beta2 = 0.999f; float beta1_power_val = 0.9f; float beta2_power_val = 0.999f; float eps = 1e-8f; float learning_rate = 0.001f; int nesterov = 0; int start = 0; int end = 2000; fp_adam_p(m, v, gradient, weight, beta1, beta2, &beta1_power_val, &beta2_power_val, eps, learning_rate, nesterov, start, end); return 0; }